/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package extension.room.phom;

import extension.game.room.Player;
import extension.room.analyse.CardSet;
import java.util.LinkedList;
import java.util.List;
import log.Debug;

/**
 *
 * @author daz
 */
public class PhomPlayer extends Player {

    public static final int EAT_CARD = 0;
    public static final int NORMAL_CARD = 1;
    public static final int SKIP = 3;
    public static final int MAIN_PHOM = 0;
    public static final int SUB_PHOM = 1;
    private List<Integer> listEatCards;
    private List<Integer> listFightCard;
    private int numberCardFights;
    private int havePhom;
//    private long moneyResult;
    private int numberLostCard;
    private LinkedList<Integer> listPhom;
    private LinkedList<CardSet> listCardSets;
    private LinkedList<Integer> listDepositCard;
    private LinkedList<Integer> listDepositTarget;
    private LinkedList<Integer> listPhomMore;
    private LinkedList<Integer> listMustShow;
    private LinkedList<Integer> listSubPhom;
    private LinkedList<CardSet> listSetFinal;
    private int showPhomOrder;
    private int totalPoint;
    private boolean isMoreFightTurn;
    private int penaltyCreatMoreTurn;
    private boolean showSubPhom;
    private int phomType;
    private boolean isShowPhom;
    private boolean isShowPhomMore;

    public PhomPlayer(String name, long money, int seatPos) {
        super(name, money, seatPos);
        listPhom = new LinkedList<Integer>();
        listEatCards = new LinkedList<Integer>();
        listFightCard = new LinkedList<Integer>();
        listDepositTarget = new LinkedList<Integer>();
        listDepositCard = new LinkedList<Integer>();
        listPhomMore = new LinkedList<Integer>();
        listMustShow = new LinkedList<Integer>();
        listSubPhom = new LinkedList<Integer>();
        listSetFinal = new LinkedList<CardSet>();
        showPhomOrder = -1;
        numberCardFights = 0;
        showPhomOrder = -1;
        isMoreFightTurn = false;
        numberLostCard = 0;
        penaltyCreatMoreTurn = -1;
        rank = 0;
    }

    public void updateLostCard() {
        numberLostCard++;
    }

    @Override
    public void resetCard() {
        listCardIds.clear();
        listEatCards.clear();
        listFightCard.clear();
        listDepositCard.clear();
        listDepositTarget.clear();
        listSubPhom.clear();
        listMustShow.clear();
        numberCardFights = 0;
        showPhomOrder = -1;
        isMoreFightTurn = false;
        numberLostCard = 0;
        penaltyCreatMoreTurn = -1;
        rank = 0;
        isShowPhom = false;
        isShowPhomMore = false;
//        havePhom = 0;
    }

    public List<Integer> getListFightCard() {
        return listFightCard;
    }

    public void addCard(int cardId, int type) {
        listCardIds.add(cardId);
        numberCardInHands++;
        if (type == EAT_CARD) {
            listEatCards.add(cardId);
        }
    }

    public void addFightedCard(int cardId) {
        listFightCard.add(cardId);
        numberCardFights = listFightCard.size();
    }

    public LinkedList<CardSet> getListCardSets() {
        return listCardSets;
    }

    void removeCardInHand(Integer cardFight) {
        for (int i = 0; i < listCardIds.size(); i++) {
            if (listCardIds.get(i) == cardFight) {
                listCardIds.remove(i);
                listFightCard.add(cardFight);
                break;
            }
        }

        numberCardInHands -= 1;
        numberCardFights++;
    }

    public void setIsShowPhomMore(boolean isShowPhomMore) {
        this.isShowPhomMore = isShowPhomMore;
    }

    public void removePhom() {
        isShowPhom = true;
        for (CardSet set : listCardSets) {
            listSetFinal.add(set);
        }
        for (Integer remove : listPhom) {
            for (Integer card : listCardIds) {
                if (remove.equals(card)) {
                    listCardIds.remove(card);
                    break;
                }
            }
        }

//        Debug.d(name + "-remove card : size :" + listPhom.size() + ", number card :" + numberCardInHands);
        numberCardInHands -= listPhom.size();
    }

    public boolean isIsShowPhomMore() {
        return isShowPhomMore;
    }

    public boolean isIsShowPhom() {
        return isShowPhom;
    }

    public void removeSubPhom() {

        for (CardSet set : listCardSets) {
            listSetFinal.add(set);
        }
        for (Integer remove : listSubPhom) {
            for (Integer card : listCardIds) {
                if (remove.equals(card)) {
                    listCardIds.remove(card);
                    break;
                }
            }
        }

//        Debug.d(name + "-remove card : size :" + listPhom.size() + ", number card :" + numberCardInHands);
        numberCardInHands -= listSubPhom.size();
    }

    public int getNumberCardFights() {
        return numberCardFights;
    }

    public int updateFightedCard(int delta) {
        int cardRemove = -1;
        if (!listFightCard.isEmpty()) {
            cardRemove = listFightCard.remove(numberCardFights - 1);
        }
        this.numberCardFights += delta;
        return cardRemove;
    }

    public int getHavePhom() {
        return havePhom;
    }

    private void filterSixPhom() {
        for (CardSet set : listCardSets) {
            if (set.getType() == CardSet.PAIR) {
                set.isRemove = true;
            }
        }
    }

    private void filterFivePhom() {
        int numberPairs = 0;
        int numberFlush = 0;
        for (CardSet set : listCardSets) {
            if (set.getType() == CardSet.PAIR) {
                numberPairs++;
            } else {
                numberFlush++;
            }
        }
        if (numberPairs == 3) {
            for (CardSet set : listCardSets) {
                if (set.getType() == CardSet.FLUSH) {
                    set.isRemove = true;
                }
            }
        } else if (numberFlush == 3) {
            for (CardSet set : listCardSets) {
                if (set.getType() == CardSet.PAIR) {
                    set.isRemove = true;
                }
            }
        }
    }

    private void filterFourPhom() {
        List<Integer> listCardDuplicate = new LinkedList<Integer>();
        int numberTwoDuplicate = 0;
        int setEatType = -1;
        int numberPair = 0;
        int numberFlush = 0;
        for (int i = 0; i < listCardSets.size(); i++) {
            CardSet set1 = listCardSets.get(i);
            set1.setNumberDuplicate(0);
            for (int j = 0; j < listCardSets.size(); j++) {

                CardSet set2 = listCardSets.get(j);
                int isDuplicate = -1;
                if (i != j) {
                    isDuplicate = set1.duplicateNotChange(set2);
                    if (set1.getType() != set2.getType() && isDuplicate != -1) {
                        set1.moreDuplicate();
                        boolean isCanAdd = true;
                        for (Integer cardDuplicate : listCardDuplicate) {
                            if (cardDuplicate.equals(isDuplicate)) {
                                isCanAdd = false;
                                break;
                            }
                        }
                        if (isCanAdd) {
                            listCardDuplicate.add(isDuplicate);
                        }
                    }
                }
            }
            if (set1.getNumberDuplicate() == 2) {
                numberTwoDuplicate++;
            }
            if (set1.isContainEatCard && set1.getSetSize() >= 4) {
                if (set1.getType() == CardSet.PAIR) {
                    setEatType = CardSet.FLUSH;
                    numberPair++;
                } else {
                    setEatType = CardSet.PAIR;
                    numberFlush++;
                }
            }

        }
        boolean isAlternative = false;
        // check xem co trung trong quan an ko
        if (!isAlternative) {
            if (listEatCards.size() == 1) {
                Integer cardEat = listEatCards.get(0);
                for (Integer cardDuplicate : listCardDuplicate) {
                    if (cardDuplicate.equals(cardEat)) {
                        isAlternative = true;
                        break;
                    }
                }
            } else if (listEatCards.size() == 2) {
                Integer cardEat1 = listEatCards.get(0);
                Integer cardEat2 = listEatCards.get(1);
                if (cardEat1 / 13 != cardEat2 / 13) {
                    int count = 0;
                    for (Integer cardDuplicate : listCardDuplicate) {
                        if (cardDuplicate.equals(cardEat1) || cardDuplicate.equals(cardEat2)) {
                            count++;
                        }
                    }
                    if (count == 2) {
                        isAlternative = true;
                    }
                }

            }
        }

        if (numberTwoDuplicate > 0) {
            if (setEatType == -1) {
                for (int i = 0; i < listCardSets.size(); i++) {
                    CardSet set1 = listCardSets.get(i);
                    if (set1.getType() == CardSet.PAIR) {
                        set1.isRemove = true;
                        listSubPhom.addAll(set1.getListCards());
                    }
                }
            } else if (setEatType == CardSet.PAIR) {
                for (int i = 0; i < listCardSets.size(); i++) {
                    CardSet set1 = listCardSets.get(i);
                    if (set1.getType() == CardSet.FLUSH) {
                        set1.isRemove = true;
                        if (isAlternative) {
                            listSubPhom.addAll(set1.getListCards());
                        }
                        CardSet setRemain = set1.extractSetAfterRemove(listCardDuplicate);
                        if (setRemain != null) {
                            listPhom.addAll(setRemain.getListCards());
                        }
                    }

                }
            } else if (setEatType == CardSet.FLUSH) {
                for (int i = 0; i < listCardSets.size(); i++) {
                    CardSet set1 = listCardSets.get(i);
                    if (set1.getType() == CardSet.PAIR) {
                        set1.isRemove = true;
                        if (isAlternative) {
                            listSubPhom.addAll(set1.getListCards());
                        }
                        if (set1.getSetSize() >= 4) {
                            for (Integer remove : listCardDuplicate) {
                                for (Integer cardCheck : set1.getListCards()) {
                                    if (cardCheck.equals(remove)) {
                                        set1.removeCard(cardCheck);
                                        break;
                                    }
                                }
                            }
                            listPhom.addAll(set1.getListCards());
                        } else {
                            for (Integer remove : set1.getListCards()) {
                                for (Integer cardCheck : listCardDuplicate) {
                                    if (cardCheck.equals(remove)) {
                                        listCardDuplicate.remove(cardCheck);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                }
            }
        } else {
            for (int i = 0; i < listCardSets.size(); i++) {
                CardSet set1 = listCardSets.get(i);
                if (set1.getNumberDuplicate() == 1) {
                    for (int j = 0; j < listCardSets.size(); j++) {
                        CardSet set2 = listCardSets.get(j);
                        if (set2.getNumberDuplicate() == 1 && i != j) {
                            set1.duplicateChange(set2);
                            if (set1.isContainEatCard && !set2.isContainEatCard) {
                                set2.isRemove = true;
                            } else if (!set1.isContainEatCard && set2.isContainEatCard) {
                                set1.isRemove = true;
                            } else {
                                set2.isRemove = true;
                                listSubPhom.addAll(set2.getListCards());
                            }
                            break;
                        }
                    }
                    break;
                }
            }
        }
//        for (CardSet set : listCardSets) {
//            if (set.isRemove && set.checkCanRemove(listCardDuplicate)) {
//                for (Integer remove : listCardDuplicate) {
//                    for (Integer card : set.getListCards()) {
//                        if (remove.equals(card)) {
//                            set.removeCard(card);
//                            break;
//                        }
//                    }
//                }
//                listPhom.addAll(set.getListCards());
//            }
//        }
    }

    private void filterThreePhom() {

        boolean isHaveDuplicateTwo = false;
        boolean isSetDuplicate = false;
        for (int i = 0; i < listCardSets.size(); i++) {
            CardSet set1 = listCardSets.get(i);
            set1.setNumberDuplicate(0);
            int isDuplicate = -1;
            for (int j = 0; j < listCardSets.size(); j++) {
                CardSet set2 = listCardSets.get(j);

                if (i != j) {
                    isDuplicate = set1.duplicateNotChange(set2);
                }
                if (set1.getType() != set2.getType() && isDuplicate != -1 && i != j) {
                    set1.moreDuplicate();
                    isSetDuplicate = true;
                }

            }
            if (set1.getNumberDuplicate() >= 2) {
                isHaveDuplicateTwo = true;
            }
        }
        if (isSetDuplicate) {
            for (int i = 0; i < listCardSets.size(); i++) {
                CardSet set1 = listCardSets.get(i);
                if (isHaveDuplicateTwo) {
                    if (set1.getNumberDuplicate() >= 2) {
                        int isHaveEatCard = 0;
                        for (int j = 0; j < listCardSets.size(); j++) {
                            CardSet set2 = listCardSets.get(j);
                            if (i != j && set2.getNumberDuplicate() == 1) {
                                if (set2.contain(listEatCards)) {
                                    isHaveEatCard++;
                                }
                            }
                        }
                        boolean isContainEatCard = set1.contain(listEatCards);
                        if (isContainEatCard && isHaveEatCard == 0) {
                            boolean isMainSet = false;
                            for (int j = 0; j < listCardSets.size(); j++) {
                                CardSet set2 = listCardSets.get(j);
                                if (i != j && set2.getNumberDuplicate() == 1) {
                                    if (!set1.checkCanRemove(set2.getListCards()) && !set2.checkCanRemove(set1.getListCards())) {
                                        set2.isRemove = true;
                                        if (set2.getSetSize() >= 5) {
                                            CardSet setRemain = set2.extractSetAfterRemove(set1.getListCards());
                                            if (setRemain != null) {
                                                listPhom.addAll(setRemain.getListCards());
                                            }
                                        }
                                    } else {
                                        set1.isRemove = true;
                                        set2.isRemove = true;
                                        CardSet temp = new CardSet(set1.getListCards(), set1.getType());
                                        temp.duplicateChange(set2);
                                        if (isMainSet) {
                                            listPhom.addAll(set1.getListCards());
                                            listPhom.addAll(set2.getListCards());
                                        } else {
                                            listSubPhom.addAll(set1.getListCards());
                                            listSubPhom.addAll(set2.getListCards());
                                        }
                                        isMainSet = !isMainSet;
                                    }
                                }
                            }
                        } else if (!isContainEatCard && isHaveEatCard > 0) {
                            if (isHaveEatCard == 2) {
                                set1.isRemove = true;
                                if (set1.getSetSize() >= 5) {
                                    List<Integer> cardRemove = new LinkedList<Integer>();
                                    for (int j = 0; j < listCardSets.size(); j++) {
                                        CardSet set2 = listCardSets.get(j);
                                        if (i != j && set2.getNumberDuplicate() == 1) {
                                            cardRemove.add(set1.duplicateNotChange(set2));

                                        }
                                    }
                                    CardSet setRemain = set1.extractSetAfterRemove(cardRemove);
                                    if (setRemain != null) {
                                        listPhom.addAll(setRemain.getListCards());
                                    }
                                }
                            } else {
                                CardSet temp = null;
                                set1.isRemove = true;
                                List<Integer> cardRemove = new LinkedList<Integer>();
                                for (int j = 0; j < listCardSets.size(); j++) {
                                    CardSet set2 = listCardSets.get(j);
                                    if (i != j && set2.getNumberDuplicate() == 1) {
                                        if (set2.isContainEatCard) {
                                            temp = new CardSet(set2.getListCards(), set2.getType());
                                        }
                                        cardRemove.add(set1.duplicateNotChange(set2));
                                    }
                                }
                                if (set1.getSetSize() >= 5) {
                                    CardSet setRemain = set1.extractSetAfterRemove(cardRemove);
                                    if (setRemain != null) {
                                        listPhom.addAll(setRemain.getListCards());
                                    }
                                }
                                int duplicate = temp.duplicateChange(set1);
                                if (duplicate == -1) {
                                    listSubPhom.addAll(temp.getListCards());
                                    listSubPhom.addAll(set1.getListCards());
                                }

                            }
                        } else if (!isContainEatCard && isHaveEatCard == 0) {
                            List<Integer> cardRemove = new LinkedList<Integer>();
                            for (int j = 0; j < listCardSets.size(); j++) {
                                CardSet set2 = listCardSets.get(j);
                                if (i != j && set2.getNumberDuplicate() == 1) {
                                    cardRemove.add(set1.duplicateNotChange(set2));
                                    set2.isRemove = true;
                                    listSubPhom.addAll(set2.getListCards());
                                    if (set2.getSetSize() >= 5) {
                                        CardSet setRemain = set2.extractSetAfterRemove(set1.getListCards());
                                        if (setRemain != null) {
                                            listPhom.addAll(setRemain.getListCards());
                                        }
                                    }
                                }

                            }
                            if (set1.getSetSize() >= 5) {
                                CardSet setRemain = set1.extractSetAfterRemove(cardRemove);
                                if (setRemain != null) {
                                    listSubPhom.addAll(setRemain.getListCards());
                                }
                            }
                        } else {
                            if (isHaveEatCard == 2) {
                                List<Integer> cardRemove = new LinkedList<Integer>();
                                set1.isRemove = true;
                                for (int j = 0; j < listCardSets.size(); j++) {
                                    CardSet set2 = listCardSets.get(j);
                                    if (i != j && set2.getNumberDuplicate() == 1) {
                                        int duplicateCard = set2.duplicateNotChange(set1);
                                        cardRemove.add(duplicateCard);
                                        CardSet setRemain = set1.extractSetAfterRemove(duplicateCard);
                                        if (setRemain != null) {
                                            listSubPhom.clear();
                                            listSubPhom.addAll(setRemain.getListCards());
                                            listSubPhom.addAll(set2.getListCards());
                                        }
                                    }
                                }
                                if (set1.getSetSize() >= 5) {
                                    CardSet setRemain = set1.extractSetAfterRemove(cardRemove);
                                    if (setRemain != null) {
                                        listPhom.addAll(setRemain.getListCards());
                                    }
                                }
                            } else {
                                CardSet setContainEat = null, setNotContainEat = null;
                                for (int j = 0; j < listCardSets.size(); j++) {
                                    CardSet set2 = listCardSets.get(j);
                                    if (i != j && set2.getNumberDuplicate() == 1) {
                                        if (set2.contain(listEatCards)) {
                                            setContainEat = set2;
                                        } else {
                                            setNotContainEat = set2;
                                        }
                                    }
                                }
                                int duplicate = setContainEat.duplicateChange(set1);
                                if (duplicate == -1) {
                                    setNotContainEat.isRemove = true;
                                    if (setNotContainEat.checkCanRemove(set1.getListCards())) {
                                        for (Integer remove : set1.getListCards()) {
                                            for (Integer cardId : setNotContainEat.getListCards()) {
                                                if (remove.equals(cardId)) {
                                                    setNotContainEat.removeCard(cardId);
                                                    break;
                                                }
                                            }
                                        }
                                        listPhom.addAll(setNotContainEat.getListCards());
                                    }
                                } else {
                                    int duplicate2 = set1.duplicateChange(setNotContainEat);
                                    set1.isRemove = true;
                                    listSubPhom.addAll(set1.getListCards());
                                    List<Integer> listRemove = new LinkedList<Integer>();
                                    listRemove.add(duplicate);
                                    listRemove.add(duplicate2);
                                    if (set1.getSetSize() >= 5 && set1.checkCanRemove(listRemove)) {
                                        set1.removeCard(duplicate);
                                        set1.removeCard(duplicate2);
                                        listPhom.addAll(set1.getListCards());
                                    }
                                }

                            }

                        }
                        break;
                    }
                } else {
                    if (set1.getNumberDuplicate() == 1) {
                        for (int j = 0; j < listCardSets.size(); j++) {
                            CardSet set2 = listCardSets.get(j);
                            if (set2.getNumberDuplicate() == 1 && i != j) {
                                int duplicate = set1.duplicateChange(set2);
                                if (duplicate != -1) {
                                    if (set1.isContainEatCard && !set2.isContainEatCard) {
                                        set2.isRemove = true;
                                    } else if (!set1.isContainEatCard && set2.isContainEatCard) {
                                        set1.isRemove = true;
                                    } else {
                                        set2.isRemove = true;
                                        listSubPhom.addAll(set2.getListCards());
                                    }
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    private void filterTwoPhom() {
        CardSet set1 = listCardSets.get(0);
        CardSet set2 = listCardSets.get(1);
        int isDuplicate = -1;
        if (set1.getType() != set2.getType()) {
            isDuplicate = set1.duplicateChange(set2);
            if (isDuplicate != -1) {
                set1.setNumberDuplicate(1);
                set2.setNumberDuplicate(1);

                if (set1.isContainEatCard && !set2.isContainEatCard) {
                    set2.isRemove = true;
                } else if (!set1.isContainEatCard && set2.isContainEatCard) {
                    set1.isRemove = true;
                } else {
                    if (set1.getListCards().size() >= 5) {
                        CardSet setRemain = set1.extractSetAfterRemove(isDuplicate);
                        if (setRemain != null) {
                            listSubPhom.addAll(setRemain.getListCards());
                        }
                        set2.isRemove = true;
                        listSubPhom.addAll(set2.getListCards());
                    } else if (set2.getListCards().size() >= 5) {
                        CardSet setRemain = set2.extractSetAfterRemove(isDuplicate);
                        if (setRemain != null) {
                            listSubPhom.addAll(setRemain.getListCards());
                        }
                        set1.isRemove = true;
                        listSubPhom.addAll(set1.getListCards());
                    } else {
                        set2.isRemove = true;
                        listSubPhom.addAll(set2.getListCards());
                    }

                }
            }

        }
    }

    private void filterPhom() {
        for (CardSet s : listCardSets) {
            if (s.contain(listEatCards)) {
                s.isContainEatCard = true;
            }
        }

        listSubPhom.clear();
        listSubPhom.addAll(listMustShow);
        int numberSets = listCardSets.size();
        if (numberSets == 2) {
            filterTwoPhom();
        } else if (numberSets == 3) {
            filterThreePhom();
        } else if (numberSets == 4) {
            filterFourPhom();
        } else if (numberSets == 5) {
            filterFivePhom();
        } else if (numberSets == 6) {
            filterSixPhom();
        }

        for (CardSet set : listCardSets) {
            if (!set.isRemove) {
                listPhom.addAll(set.getListCards());
                if (set.getNumberDuplicate() == 0 && !listSubPhom.isEmpty()) {
                    listSubPhom.addAll(set.getListCards());
                }
            }
        }
        if (listSubPhom.size() >= 9 && listPhom.size() < 9) {
            listPhom.clear();
            listPhom.addAll(listSubPhom);
        }
        showSubPhom = false;
    }

    public LinkedList<Integer> getListPhom() {
        return listPhom;
    }

    public LinkedList<Integer> getListSubPhom() {
        if (listSubPhom.size() > listMustShow.size() && !listSubPhom.isEmpty()) {
            return listSubPhom;
        }
        return null;
    }

    public void generateListPhom() {
        if (!isMoreFightTurn) {
            extracPhom();
            filterPhom();
        } else {
            int numberCards = listCardIds.size();
            int[] listCards = new int[numberCards];
            for (int i = 0; i < numberCards; i++) {
                listCards[i] = listCardIds.get(i);
            }
            int numberSets = listCardSets.size();
            extractFlush(listCards);
            extractPair(listCards);
            listPhomMore = new LinkedList<Integer>();
            if (numberSets < listCardSets.size()) {
                //find more fom
                CardSet set = listCardSets.get(numberSets);
                listPhomMore.clear();
                listPhomMore.addAll(set.getListCards());
                listPhom.addAll(set.getListCards());
            }
            listSubPhom.clear();
        }
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public int getRank() {
        return rank;
    }

    private void extracPhom(int cardFight) {
        listCardSets = new LinkedList<CardSet>();
        int numberCards = listCardIds.size() + 1;
        int[] listCards = new int[numberCards];
        for (int i = 0; i < numberCards - 1; i++) {
            listCards[i] = listCardIds.get(i);
        }
        listCards[numberCards - 1] = cardFight;
        listCardSets.clear();
        extractFlush(listCards);
        extractPair(listCards);
    }

    private void extracPhom() {
        listCardSets = new LinkedList<CardSet>();
        listPhom.clear();
        listPhom.addAll(listMustShow);
        listCardIds.removeAll(listMustShow);
        int numberCards = listCardIds.size();
        int[] listCards = new int[numberCards];
        for (int i = 0; i < numberCards; i++) {
            listCards[i] = listCardIds.get(i);
        }
        listCardSets.clear();
        extractFlush(listCards);
        extractPair(listCards);
    }

    int checkEatCard(int cardFight) {
        if (listCardIds.size() <= 2) {
            return 0;
        }
        if (listEatCards.size() >= 3) {
            return 0;
        }
        List<Integer> listNotSameSet = new LinkedList<Integer>();
        List<Integer> listInTwoSet = new LinkedList<Integer>();
        extracPhom(cardFight);
        if (!listEatCards.isEmpty()) {
            for (Integer cardEat : listEatCards) {
                int count = 0;
                for (CardSet set : listCardSets) {
                    if (set.contain(cardEat)) {
                        set.isContainEatCard = true;
                        set.addEatCard(cardEat);
                        if (set.getType() == CardSet.PAIR) {
                            listNotSameSet.addAll(set.getListCards());
                        } else {
                            listNotSameSet.addAll(set.getNearCard(cardEat));
                        }
                        count++;
                    }
                    //appear in  2 set
                    if (count == 2) {
                        listInTwoSet.add(cardEat);
                        for (CardSet setCheck : listCardSets) {
                            if (setCheck.contain(cardEat)) {

                                break;
                            }
                        }

                    }
                }
            }
        }
        ///last opportunity
        if (!listInTwoSet.isEmpty()) {
            for (Integer card : listInTwoSet) {
                for (int i = 0; i < listCardSets.size() - 1; i++) {
                    CardSet set1 = listCardSets.get(i);
                    if (set1.contain(card)) {
                        for (int j = i + 1; j < listCardSets.size(); j++) {
                            CardSet set2 = listCardSets.get(j);
                            if (set2.contain(card)) {
                                if (set1.getListEatCards().size() == 1 && set2.getListEatCards().size() == 1) {
                                    if (set2.checkCanRemove(card)) {
                                        for (Integer remove : set2.getListCards()) {
                                            for (Integer cardId : listNotSameSet) {
                                                if (remove.equals(cardId)) {
                                                    listNotSameSet.remove(cardId);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (set1.checkCanRemove(card)) {
                                        for (Integer remove : set1.getListCards()) {
                                            for (Integer cardId : listNotSameSet) {
                                                if (remove.equals(cardId)) {
                                                    listNotSameSet.remove(cardId);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                } else if (set1.checkCanRemove(set1.getListEatCards())) {
                                    for (Integer remove : set1.getListCards()) {
                                        for (Integer cardId : listNotSameSet) {
                                            if (remove.equals(cardId)) {
                                                listNotSameSet.remove(cardId);
                                                break;
                                            }
                                        }
                                    }
                                } else if (set2.checkCanRemove(set2.getListEatCards())) {
                                    for (Integer remove : set2.getListCards()) {
                                        for (Integer cardId : listNotSameSet) {
                                            if (remove.equals(cardId)) {
                                                listNotSameSet.remove(cardId);
                                                break;
                                            }
                                        }
                                    }
                                }
                                break;

                            }
                        }
                    }
                }

            }
        }


        for (CardSet cardSet : listCardSets) {
            if (cardSet.contain(cardFight)) {
                //ko chua phom da an
                if (!cardSet.contain(listNotSameSet)) {
                    return 1;
                }
                //day dong chat
                if (cardSet.getSetSize() > 5) {
                    CardSet setRemain = cardSet.extractSetAfterRemove(listNotSameSet);
                    if (setRemain != null) {
                        if (setRemain.contain(cardFight)) {
                            return 1;
                        }
                        return 0;
                    }

                }

                if (cardSet.checkCanRemove(listNotSameSet)) {
                    return 1;
                }
                for (CardSet setCheck : listCardSets) {
                    if (setCheck.isContainEatCard) {
                        int duplicate = setCheck.duplicateNotChange(cardSet);
                        if (setCheck.checkCanRemove(cardSet.getListCards())) {
                            boolean isChoose = true;
                            for (Integer cardEat : listEatCards) {
                                if (cardEat.equals(duplicate)) {
                                    isChoose = false;
                                    break;
                                }
                            }
                            if (isChoose) {
                                return 1;
                            }
                        }
                    }
                }
            }
        }


        return 0;
    }

    private static void printListCardId(int[] listCards) {
        int numberCard = listCards.length;
        for (int i = 0; i < numberCard; i++) {
            System.out.print(listCards[i] + ",");
        }
    }

    private void extractPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }
        //tim phom ngang
        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    if (j < numberCards - 1 && cardId % 13 == listCards[j + 1] % 13) {
                        if (j < numberCards - 2 && cardId % 13 == listCards[j + 2] % 13) {
//                            Debug.d("bo bon");
                            step = 3;
                        } else {
//                            Debug.d("bo ba");
                            step = 2;
                        }
                    } else {
//                        Debug.d("bo 2");
                        step = 1;
                    }
                    int[] pair = new int[step + 1];
                    for (int k = i; k <= i + step; k++) {
                        pair[k - i] = listCards[k];
//                        Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                    }
                    if (step >= 2) {
                        CardSet pairSet = new CardSet(pair, CardSet.PAIR);
                        listCardSets.add(pairSet);
//                        Debug.d("set :" + pairSet.toString());
                    }

//                    Debug.d("");
                    j = numberCards;
                    i = i + step;
                }
            }
        }
    }

    private void extractFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] / 13 > listCards[j] / 13
                        || (listCards[i] / 13 == listCards[j] / 13
                        && listCards[i] % 13 > listCards[j] % 13)) {
                    swap(i, j, listCards);
                }
            }
        }
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int cardId = listCards[i];
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId + (j - i) == listCards[j] && cardId / 13 == listCards[j] / 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
            if (step != 0) {
                int[] flsush = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    flsush[k - i] = listCards[k];
                }
                if (step >= 2) {
                    CardSet flushSet = new CardSet(flsush, CardSet.FLUSH);
                    listCardSets.add(flushSet);
                }
                i = i + step;
            }

        }
    }

    private static boolean checkPair(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] % 13 > listCards[j] % 13) {
                    int temp = listCards[j];
                    listCards[j] = listCards[i];
                    listCards[i] = temp;
                }
            }
        }

        for (int i = 0; i < numberCards; i++) {
            int cardId = listCards[i];
            int step = 0;
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId % 13 == listCards[j] % 13) {
                    if (j < numberCards - 1 && cardId % 13 == listCards[j + 1] % 13) {
                        if (j < numberCards - 2 && cardId % 13 == listCards[j + 2] % 13) {
//                            Debug.d("bo bon");
                            step = 3;
                        } else {
//                            Debug.d("bo ba");
                            step = 2;
                        }
                    } else {
//                        Debug.d("bo 2");
                        step = 1;
                    }
                    int[] pair = new int[step + 1];
                    for (int k = i; k <= i + step; k++) {
                        pair[k - i] = listCards[k];
//                        Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                    }
                    if (step >= 2) {
                        return true;
                    }
//                    Debug.d("");
                    j = numberCards;
                    i = i + step;
                }
            }
        }
        return false;
    }

    private static boolean checkFlush(int[] listCards) {
        int numberCards = listCards.length;
        for (int i = 0; i < numberCards; i++) {
            for (int j = i + 1; j < numberCards; j++) {
                if (listCards[i] / 13 > listCards[j] / 13
                        || (listCards[i] / 13 == listCards[j] / 13
                        && listCards[i] % 13 > listCards[j] % 13)) {
                    swap(i, j, listCards);
                }
            }
        }
        for (int i = 0; i < numberCards; i++) {
            int step = 0;
            int cardId = listCards[i];
            for (int j = i + 1; j < numberCards; j++) {
                if (cardId + (j - i) == listCards[j] && cardId / 13 == listCards[j] / 13) {
                    step++;
                } else {
                    j = numberCards;
                }
            }
            if (step != 0) {
//                Debug.d("day :" + step);
                int[] flsush = new int[step + 1];
                for (int k = i; k <= i + step; k++) {
                    flsush[k - i] = listCards[k];
//                    Debug.n(Card.getRank(listCards[k]) + Card.getSuit(listCards[k]));
                }
                if (step >= 2) {
                    return true;
                }
                i = i + step;
            }
        }
        return false;
    }

    private static void swap(int i, int j, int[] listCards) {
        int temp = listCards[j];
        listCards[j] = listCards[i];
        listCards[i] = temp;
    }

    public void setShowPhomOrder(int showPhomOrder) {
        this.showPhomOrder = showPhomOrder;
        if (!listPhom.isEmpty()) {
            havePhom = 1;
        } else {
            if (!isMoreFightTurn) {
                havePhom = 0;
            }
        }
        if (isMoreFightTurn) {
            if (!listPhomMore.isEmpty()) {
                havePhom = 1;
            }
        }
    }

    public void clearPhomFinal() {
        listSetFinal.clear();
    }

//    public void setHavePhom(int havePhom) {
//        this.havePhom = havePhom;
//    }
    public int getShowPhomOrder() {
        return showPhomOrder;
    }

    void sumPoint() {
        totalPoint = 0;
        for (Integer card : listCardIds) {
            totalPoint += ((card % 13) + 1);
        }
    }

    public int getTotalPoint() {
        if (havePhom == 1) {
            return totalPoint;
        }
        return 100;
    }

    void updateMoney(long moneyChange) {
        Debug.d(name + " update money before :" + money);
        this.money += moneyChange;
        Debug.d(name + " update money after :" + money);
    }

    void updateMoneyChange() {
        Debug.d(name + " update money before :" + money);
        this.money += this.moneyChange;
        Debug.d(name + " update money after :" + money);

    }

    void addEatCard(int cardFight) {
        listEatCards.add(cardFight);
    }

    public List<Integer> getListEatCards() {
        return listEatCards;
    }

    public void resetDeposit() {
        listDepositCard.clear();
        listDepositTarget.clear();
    }

    void generateDepositCard(LinkedList<CardSet> listCardSets, int seatPos) {

        List<Integer> listChecks = new LinkedList<Integer>();
        List<CardSet> listSetChecks = new LinkedList<CardSet>();
        for (Integer card : listCardIds) {
            listChecks.add(card);
        }

        if (!listDepositCard.isEmpty()) {
            for (Integer remove : listDepositCard) {
                for (Integer card : listChecks) {
                    if (remove.equals(card)) {
                        listChecks.remove(card);
                        break;
                    }
                }
            }
        }

        for (CardSet set : listCardSets) {
            listSetChecks.add(set);
        }

        for (CardSet set : listSetChecks) {
            int checkIndex = 0;
            do {
                Integer card = listChecks.get(checkIndex);
                if (!set.isRemove && set.canAddToSet(card)) {
                    listDepositCard.add(card);
                    listDepositTarget.add(seatPos);
                    set.addCard(card);
                    listChecks.remove(card);
                    checkIndex = 0;
                } else {
                    checkIndex++;
                }
            } while (checkIndex < listChecks.size());
        }

        if (!listDepositCard.isEmpty()) {
            for (CardSet set : listSetChecks) {
                for (Integer remove : listDepositCard) {
                    for (Integer card : set.getListCards()) {
                        if (remove.equals(card)) {
                            set.removeCard(remove);
                            break;
                        }
                    }
                }
            }
        }


    }

    public LinkedList<Integer> getListDepositCard() {
        return listDepositCard;
    }

    public LinkedList<Integer> getListDepositTarget() {
        return listDepositTarget;
    }

    void addToPhom(List<Integer> depositCard) {
        List<Integer> listCheck = new LinkedList<Integer>();
        for (Integer card : depositCard) {
            listCheck.add(card);
        }

        for (CardSet set : listSetFinal) {
            int checkIndex = 0;
            if (!listCheck.isEmpty()) {
                do {
                    Integer card = listCheck.get(checkIndex);
                    if (!set.isRemove && set.canAddToSet(card)) {
                        set.addCard(card);
                        listCheck.remove(card);
                        checkIndex = 0;
                    } else {
                        checkIndex++;
                    }
                } while (checkIndex < listCheck.size() && !listCheck.isEmpty());
            }
        }
        listPhom.clear();
        for (CardSet set : listSetFinal) {
            listPhom.addAll(set.getListCards());
        }
    }

    void moreFightTurn() {
        if (numberCardFights == PhomGame.numberCardFinish - 1) {
            Debug.i(name + ":more fight turn :" + isMoreFightTurn);
            isMoreFightTurn = true;
        }
    }

    public boolean getIsMoreFightTurn() {
        return isMoreFightTurn;
    }

    public void setIsMoreFightTurn(boolean isMoreFightTurn) {
        this.isMoreFightTurn = isMoreFightTurn;
    }

    public LinkedList<Integer> getListPhomMore() {
        return listPhomMore;
    }

    public int getNumberLostCard() {
        return numberLostCard;
    }

    public void setPenaltyCreatMoreTurn(int penaltyCreatMoreTurn) {
        this.penaltyCreatMoreTurn = penaltyCreatMoreTurn;
    }

    public int getPenaltyCreatMoreTurn() {
        return penaltyCreatMoreTurn;
    }

    public boolean isShowSubPhom() {
        return showSubPhom;
    }

    public void setShowSubPhom(boolean showSubPhom) {
        this.showSubPhom = showSubPhom;
    }

    public void setPhomType(int phomType) {
        this.phomType = phomType;
    }

    public int getPhomType() {
        return phomType;
    }

    public boolean containCard(Integer cardFight) {
        for (Integer card : listCardIds) {
            if (card.equals(cardFight)) {
                return true;
            }
        }
        return false;
    }

    public int getCardCanFight() {
        List<Integer> listNotSameSet = new LinkedList<Integer>();
        listCardSets = new LinkedList<CardSet>();
        int numberCards = listCardIds.size();
        int[] listCards = new int[numberCards];
        for (int i = 0; i < numberCards; i++) {
            listCards[i] = listCardIds.get(i);
        }
        listCardSets.clear();
        extractFlush(listCards);
        extractPair(listCards);
        if (!listEatCards.isEmpty()) {
            for (Integer cardEat : listEatCards) {
                for (CardSet set : listCardSets) {
                    if (set.contain(cardEat)) {
                        listNotSameSet.addAll(set.getListCards());
                    }
                }
            }

        }
        for (int i = 0; i < numberCards; i++) {
            boolean isChoose = true;
            for (Integer card : listNotSameSet) {
                if (card.equals(listCards[i])) {
                    isChoose = false;
                    break;
                }
            }
            if (isChoose) {
                return listCards[i];
            }
        }
        return listCards[0];
    }

    public boolean breakSet(int cardFight) {
        List<Integer> listNotSameSet = new LinkedList<Integer>();
        listCardSets = new LinkedList<CardSet>();
        int numberCards = listCardIds.size();
        int[] listCards = new int[numberCards];
        for (int i = 0; i < numberCards; i++) {
            listCards[i] = listCardIds.get(i);
        }
        listCardSets.clear();
        extractFlush(listCards);
        extractPair(listCards);
        for (int i = 0; i < listCardSets.size(); i++) {
            CardSet set1 = listCardSets.get(i);
            set1.setNumberDuplicate(0);
            for (int j = 0; j < listCardSets.size(); j++) {
                CardSet set2 = listCardSets.get(j);
                int isDuplicate = -1;
                if (i != j) {
                    isDuplicate = set1.duplicateChange(set2);
                }
                if (set1.getType() != set2.getType() && isDuplicate != -1 && i != j) {
                    set1.moreDuplicate();
                }

            }
//            if (set1.getNumberDuplicate() >= 2) {
//                isHaveDuplicateTwo = true;
//            }
        }
        if (!listEatCards.isEmpty()) {
            for (Integer cardEat : listEatCards) {
                int count = 0;
                for (CardSet set : listCardSets) {
                    if (set.contain(cardEat)) {
                        for (Integer cardAdd : set.getListCards()) {
                            if (!set.checkCanRemove(cardAdd)) {
                                listNotSameSet.add(cardAdd);
                            }
                        }
                        count++;
                    }
                    //appear in  2 set
                    if (count == 2) {
                        for (CardSet set1 : listCardSets) {
                            if (set1.contain(cardEat)) {
                                for (Integer remove : set1.getListCards()) {
                                    for (Integer card : listNotSameSet) {
                                        if (remove.equals(card)) {
                                            listNotSameSet.remove(card);
                                            break;
                                        }
                                    }
                                }
                                for (Integer remove : set.getListCards()) {
                                    for (Integer card : listNotSameSet) {
                                        if (remove.equals(card)) {
                                            listNotSameSet.remove(card);
                                            break;
                                        }
                                    }
                                }

                                break;
                            }
                        }
                    }
                }

            }
            for (Integer card : listNotSameSet) {
                if (card.equals(cardFight)) {
                    return true;
                }
            }
            return false;
        }
        return false;
    }

    public LinkedList<CardSet> getListSetFinal() {
        return listSetFinal;
    }
}
